﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GOFconsole
{
    public class Chapter22_Bridge
    {
        public void BridgeTest()
        { 
            //模型
            Abstraction ab = new RefinedAbstaction();

            ab.SetImplementor(new ConcreteImplementorA());
            ab.Operation();

            ab.SetImplementor(new ConcreteImplementorB());
            ab.Operation();

            //DEMO
            //从手机软件和手机品牌的角度去抽象，如果要添加一个新功能，
            //只要添加一个对应的手机软件的子类，添加品牌也是同理，不影响其他任何一个类,符合开闭原则
            //如果只用手机品牌作为抽象，M品牌和N品牌继承于抽象品牌，游戏和通讯录再继承于M品牌和N品牌，
            //这样每添加一个新品牌或者新软件就需要改动基类，难以扩展
            
            HandsetBrand hb;

            hb = new HandsetBrandN();   //N品牌的手机
            hb.SetHandsetSoft(new HandsetGame());           //添加游戏
            hb.Run();
            hb.SetHandsetSoft(new HandsetAddressList());    //添加通讯录
            hb.Run();

            hb = new HandsetBrandM();   //M品牌的手机
            hb.SetHandsetSoft(new HandsetGame());
            hb.Run();
            hb.SetHandsetSoft(new HandsetAddressList());
            hb.Run();

        }
    }

    #region 模型
    abstract class Implementor   //抽象实现类
    {
        public abstract void Operation();
    }
    class ConcreteImplementorA : Implementor
    {
        public override void Operation()
        {
            Console.WriteLine("具体实现A的方法执行");
        }
    }
    class ConcreteImplementorB : Implementor
    {
        public override void Operation()
        {
            Console.WriteLine("具体实现B的方法执行");
        }
    }

    class Abstraction  //抽象的类
    {
        protected Implementor imp;

        public void SetImplementor(Implementor imp)
        {
            this.imp = imp;
        }
        public virtual void Operation()
        {
            imp.Operation();
        }
    }
    class RefinedAbstaction : Abstraction   //提炼的抽象类
    {
        public override void Operation()
        {
            imp.Operation();
        }
    }

    #endregion

    #region Demo(手机及其软件应用)
    abstract class HandsetSoft  //手机软件
    {
        public abstract void Run(); 
    }
    class HandsetGame : HandsetSoft
    {
        public override void Run()
        {
            Console.WriteLine("运行手机游戏");
        }
    }
    class HandsetAddressList : HandsetSoft
    {
        public override void Run()
        {
            Console.WriteLine("运行手机通讯录");
        }
    }

    //桥接模式的核心意图就是把这些实现独立出来，让它们各自的变化
    abstract class HandsetBrand //手机品牌
    {
        protected HandsetSoft hs;
        public void SetHandsetSoft(HandsetSoft hs)  //品牌需要关注软件，所以可在机器中安装软件
        {
            this.hs = hs;
        }

        public abstract void Run();
    }
    class HandsetBrandM : HandsetBrand
    {
        public override void Run()
        {
            hs.Run();
        }
    }
    class HandsetBrandN : HandsetBrand
    {
        public override void Run()
        {
            hs.Run();
        }
    }

    #endregion 
}
